package com.wnxy.admin.service.impl;

import cn.hutool.jwt.signers.JWTSigner;
import cn.hutool.jwt.signers.JWTSignerUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.wnxy.admin.common.handler.Asserts;
import com.wnxy.admin.common.handler.BusinessEnum;
import com.wnxy.admin.common.util.TokenUtil;
import com.wnxy.admin.dto.CustomerDto;
import com.wnxy.admin.dto.PermissionMenuVO;
import com.wnxy.admin.dto.StaffDto;
import com.wnxy.admin.dto.StaffMenuVO;
import com.wnxy.admin.entity.Permission;
import com.wnxy.admin.entity.Staff;
import com.wnxy.admin.mapper.StaffMapper;
import com.wnxy.admin.service.IStaffService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 员工表 服务实现类
 * </p>
 *
 * @author All
 * @since 2023-11-29
 */
@Service
public class StaffServiceImpl extends ServiceImpl<StaffMapper, Staff> implements IStaffService {

    @Value("${jwt.signature}")
    private String signature;
    @Value("${jwt.timeout}")
    private Integer timeout;
    private final StaffMapper staffMapper;


    private final StringRedisTemplate stringRedisTemplate;

    public StaffServiceImpl(StaffMapper staffMapper, StringRedisTemplate stringRedisTemplate) {
        this.staffMapper = staffMapper;
        this.stringRedisTemplate = stringRedisTemplate;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add(Staff staff) {
        //员工编号自动生成
        String code = "GAIBANG" + UUID.randomUUID().toString().replace("-", "").substring(0, 5);
        //判断编号是否存在
        boolean flag = staffMapper.exists(Wrappers.lambdaQuery(Staff.class).eq(Staff::getCode, code));
        Asserts.fail(flag == true, BusinessEnum.CODE_EXISTS);
        staff.setCode(code);
        //加入数据库
        staffMapper.insert(staff);
    }

    @Override
    public Staff login(StaffDto staffDto) {
        //获取redis验证码
        String value = stringRedisTemplate.opsForValue().get(staffDto.getCodeKey());
        //判断空值和校验
        Asserts.fail(!StringUtils.hasLength(staffDto.getValiCode()), BusinessEnum.VALICODE_IS_NULL);
        Asserts.fail(!staffDto.getValiCode().equals(value), BusinessEnum.VALICODE_IS_ERROR);

        Staff staff = staffMapper.selectOne(Wrappers.lambdaQuery(Staff.class)
                .eq(Staff::getAccount, staffDto.getAccount())
                .eq(Staff::getPassword, staffDto.getPassword()));
        Asserts.fail(Objects.isNull(staff), BusinessEnum.LOGIN_ERROR);

        return staff;
    }

    @Override
    public PageInfo<Staff> getAll(Integer pageNum, Integer pageSize, String keyword) {
        PageHelper.startPage(pageNum, pageSize);
        List<Staff> staffs = staffMapper.selectAll(keyword);
        return new PageInfo<>(staffs);
    }

    @Override
    public List<StaffMenuVO> findAll() {
        List<Staff> list = staffMapper.selectList(null);

        List<Staff> finalList = list;
        List<StaffMenuVO> menuVOS = list.stream().map(e -> {
            StaffMenuVO menuVO = new StaffMenuVO();

            //设置属性
            menuVO.setId(e.getId());
            menuVO.setName(e.getName());
            return menuVO;
        }).collect(Collectors.toList());
        return menuVOS;
    }

    @Override
    public List<String> getName(List<Integer> ids) {
        List<String> list = ids.stream()
                .map(e -> staffMapper.getName(e))
                .collect(Collectors.toList());
        return list;
    }

    private String extracted(Staff staff, HttpServletRequest request) {
        final JWTSigner signer = JWTSignerUtil.hs256(signature.getBytes());
        Map<String, Object> payload = new HashMap<>();
        String ip = getIp(request);
        //第4步：返回前端
        payload.put("ip", ip);
        payload.put("staffId", String.valueOf(staff.getId()));
        //创建Token
        return TokenUtil.createToken(payload, signature, timeout);
    }

    //用3种方法尝试获取ip地址
    public String getIp(HttpServletRequest request) {
        String ipAddress = request.getHeader("X-Forwarded-For");
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("Proxy-Client-IP");
        }
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getRemoteAddr();
        }
        return ipAddress.split(",")[0];
    }
}
